package pl.edu.agh.logview.graph;

import java.sql.SQLException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.swing.plaf.SliderUI;

import pl.edu.agh.logview.configuration.Configuration;
import pl.edu.agh.logview.database.DbHelper;
import pl.edu.agh.logview.model.Agent;
import pl.edu.agh.logview.model.AgentEdge;
import pl.edu.agh.logview.model.Edge;
import pl.edu.agh.logview.model.EdgeType;
import pl.edu.agh.logview.model.Message;
import pl.edu.agh.logview.model.MessageEdge;
import pl.edu.agh.logview.model.MessageVertex;
import pl.edu.agh.logview.model.State;
import pl.edu.agh.logview.model.Vertex;
import pl.edu.agh.logview.model.VertexType;

import com.j256.ormlite.dao.Dao;

public class GraphManager {

	private DbHelper db;
	
	public GraphManager() {
		db = new DbHelper();
//		createTestData();
	}
	
	private Date lastDate = null;
	private Date firstDate = null;
	
	
	public void createTestData() {
		
		Dao<Agent,String> agentDao = db.getAgentDao();
		Dao<State,Long> stateDao = db.getStateDao();
		Dao<Message,Long> messageDao = db.getMessageDao();
		
		Agent agent = new Agent();
		agent.setName("agent1");
		agent.setVertexType(VertexType.VERTEX_AGENT);
		
		Agent agent2 = new Agent();
		agent2.setName("agent2");
		agent2.setVertexType(VertexType.VERTEX_AGENT);
		
		
		Message m = new Message();
		m.setActionTime(new Date());
		m.setAgentFrom(agent);
		m.setAgentTo(agent2);
		m.setMessage("MSGMSMG");
		
		
		try {
			Thread.sleep(915);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		State s = new State();
		s.setActionTime(new Date());
		s.setName("staate");
		s.setAgent(agent);
		

		
		
		State s2 = new State();
		try {
			Thread.sleep(1115);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		s2.setActionTime(new Date());
		s2.setName("staate2");
		s2.setAgent(agent2);
		
		try {
			agentDao.createIfNotExists(agent);
			agentDao.createIfNotExists(agent2);
			stateDao.createIfNotExists(s);
			stateDao.createIfNotExists(s2);
			messageDao.createIfNotExists(m);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	
	public int getYFromDate(Date date) {
		
		System.out.println(lastDate.getTime() - firstDate.getTime());
		
		
		int y = (int) ( (date.getTime()-firstDate.getTime())  * 
				((Configuration.END_Y - Configuration.START_Y )) / (lastDate.getTime() - firstDate.getTime()) ) +  Configuration.SPACE + Configuration.VERTEX_AGENT_HEIGHT;
		
//		AxisVertex av = new AxisVertex();
//		av.setY(y);
//		av.setX(Configuration.AXIS_X);
//		av.setMessage(date.toString());
//		axis.add(av);
		
		return y;
	}
	
	List<Edge> edges;
	public List<Vertex> getAllVertices() {
		
		LinkedList<Vertex> result = new LinkedList<Vertex>();
		edges = new LinkedList<Edge>();
		Dao<Agent,String> agentDao = db.getAgentDao();
		Dao<State,Long> stateDao = db.getStateDao();
		Dao<Message,Long> messageDao = db.getMessageDao();
		try {
			if(stateDao.queryBuilder().orderBy("actionTime", false).limit(1).query() == null || messageDao.queryForAll().size() == 0)
				return null;
			lastDate = stateDao.queryBuilder().orderBy("actionTime", false).limit(1).query().get(0).getActionTime().getTime()
					>	messageDao.queryBuilder().orderBy("actionTime", false).limit(1).query().get(0).getActionTime().getTime() ? 
						stateDao.queryBuilder().orderBy("actionTime", false).limit(1).query().get(0).getActionTime() :
						messageDao.queryBuilder().orderBy("actionTime", false).limit(1).query().get(0).getActionTime();

			
			
			firstDate = stateDao.queryBuilder().orderBy("actionTime", true).limit(1).query().get(0).getActionTime().getTime() <
					messageDao.queryBuilder().orderBy("actionTime", true).limit(1).query().get(0).getActionTime().getTime() ?
				 stateDao.queryBuilder().orderBy("actionTime", true).limit(1).query().get(0).getActionTime() :
					messageDao.queryBuilder().orderBy("actionTime", true).limit(1).query().get(0).getActionTime();
					
					
					
			int agentCnt = 0;
			for (Agent agent : agentDao.queryForAll() ) {
				agent.setVertexType(VertexType.VERTEX_AGENT);
				agent.setX( Configuration.START_X + agentCnt*(Configuration.SPACE+agent.getVertexType().getWidth()) );
				agent.setY(Configuration.START_Y);
				agentDao.update(agent);
				result.add(agent);
				State previousState = null;
				for (State state : stateDao.queryForEq("agent_id", agent)) {
					state.setVertexType(VertexType.VERTEX_STATE);
					state.setX(agent.getCenterX() - (int)(state.getVertexType().getWidth()/2));
					state.setY(getYFromDate(state.getActionTime()));
					result.add(state);
					
					System.out.println("dodano stan: " + state.getX() + " " + state.getY() );
					Edge e = new AgentEdge();
					
					if (previousState == null) {
						e.setFrom(agent);
						e.setTo(state);
					} else {
						e.setFrom(previousState);
						e.setTo(state);
					}
					edges.add(e);
					previousState = state;
				}
				agentCnt++;
			}
			
			// message
			for (Message m : messageDao.queryForAll()) {
				agentDao.refresh(m.getAgentFrom());
				agentDao.refresh(m.getAgentTo());
				Vertex e1 = new MessageVertex();
				e1.setX( m.getAgentFrom().getCenterX() );
				e1.setY( getYFromDate(m.getActionTime()) );
				result.add(e1);
				Vertex e2 = new MessageVertex();
				e2.setX( m.getAgentTo().getCenterX() );
				e2.setY( getYFromDate( m.getActionTime()) );
				result.add(e2);
				Edge e = new MessageEdge();
				e.setFrom(e1);
				e.setTo(e2);
				e.setMessage(m.getMessage());
				System.out.println(m.getMessage());
				edges.add(e);
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public List<Edge> getAllEdges() {
		return edges;
	}
}
